#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>

#define key 0x1234567

int semid = 0;

union semun {
	int val;
	struct semid_ds *buf;
	unsigned short  *array;
};

static void _set(int val)
{
	union semun setval;
	setval.val = val;
	semctl(semid, 0, SETVAL, setval);
}

static void _setall(int val)
{
	unsigned short val_s[2] = {val, val};
	union semun setval;
	setval.array = val_s;
	semctl(semid, 0, SETALL, setval);
}

static void _up()
{
	struct sembuf buf[1] = {{0, 1, SEM_UNDO}};
	semop(semid, buf, 1);
	printf("semop  semid=%d\n", semid);
}

static void _down()
{
	struct sembuf buf[1] = {{0, -1, SEM_UNDO}};
	semop(semid, buf, 1);
	printf("semop  semid=%d\n", semid);
}

static void _get()
{
	printf("get 0 value=%d\n", semctl(semid, 0, GETVAL));
	printf("get 1 value=%d\n", semctl(semid, 1, GETVAL));
}

static void _getall()
{
	int ret = 0;
	unsigned short val_s[2] = {0};
	union semun val;
	val.array = val_s;
	ret = semctl(semid, 0, GETALL, val);
	if (ret == -1)
		printf("errno=%d\n", errno);

	printf("getall value=%u, val_s[0]=%u, val_s[1]=%u\n", ret, val_s[0], val_s[1]);
}

static void _del()
{
	semctl(semid, 0, IPC_RMID);
}

static void _init()
{
	semid = semget(key, 2, IPC_CREAT | IPC_EXCL | 0644);
	printf("create semid=%d\n", semid);
	if(semid < 0)
	{
		if( errno == EEXIST)
		{
			semid = semget(key, 2, 0644);
			return;
		}
		else
			_del();
	}

	_setall(10);
}


int main(int argc, char **argv)
{
	_init();
	//_setall(10);
	printf("begin\n");
	_get();
	_down();
	printf("in it\n");
	_getall();
	//sleep(20);
	_up();
	_get();
	printf("end\n");

	return 0;
}

